﻿/**
  KCAKCAK   CAKCAKC   AK      CA
 AK        KC     CA  AK    AK
CA         KC     CA  AK  KC
CA         KCAKCAKCA  AKCA
CA         KC     CA  AK  KC
 AK        KC     CA  AK    AK
  KCAKCAK  KC     CA  AK      CA

_________________________________________________________________
 China ataca Kamchatka - copyright 2007(c) Ruben Sainz de la Maza
 
	@class: 	GameEngine
	@vertion: 	0.1
	@date:		28/11/07
				
	@language: 	ActionScript 3.0
	@author:	Ruben Sainz de la Maza
	@usage: 
		_objGameEngine = GameEngine.getInstance();
			
**/ 
 				
 
package com.conelmate.cak.game
{
	import com.conelmate.util.Trace;
	import com.conelmate.cak.players.Players;
	import com.conelmate.cak.board.data.CAKdata;
	import com.conelmate.cak.board.countries.Countries;
	import com.conelmate.cak.board.cards.Cards;
	import com.conelmate.cak.game.rounds.Rounds;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	
	
	public class GameEngine extends Trace
	{
		static internal var	_INSTANCE		:GameEngine;		//instancia de esta clase (singleton)
		static	private var _PARENT			:DisplayObject;		//ref al root

				private	var _isInited		:Boolean = false;	//false:la clase aun no ha sido iniciada
				private var	_isFreeze		:Boolean = false;	//true:congela eventos, false:reactiva eventos
		
				private var	_objPlayers		:Players;			//ref
				private	var _objCountries	:Countries;			//ref
				private	var _objCards		:Cards;				//ref		
				private	var _objRounds		:Rounds;			//ref	
		
				private var _mcGameBoard;						//attach library game/board/mcs/board/mcGameBoard
				private var _mcMap;								//attach library game/board/mcs/board/mcMap
				private var _mcLimits;							//attach library game/board/mcs/board/mcLimitsCountries
		

//_________________________________________________________________________________ Constructor
		public function GameEngine(enforcer:SingletonEnforcer)
		{
			_isTrace = false;
			mTrace("#GameEngine# constructor");	
		}
		

//_________________________________________________________________________________ Public Methods

		/**
		 * Singleton.  Devuelve una instancia unica de esta clase
		 */
		public static function getInstance():GameEngine
		{
			if(GameEngine._INSTANCE == null) GameEngine._INSTANCE = new GameEngine(new SingletonEnforcer());
			return GameEngine._INSTANCE;
		}
		
		
		/**
		 * Inicializa la clase
		 */
		public function init(parent:DisplayObject = null):void
		{
	
			if(!_isInited){
				mTrace("#GameEngine# init");
				_isInited = true;
				_PARENT = parent || _PARENT;
				
				_mcGameBoard = new mcGameBoard();			//attach library game/board/mcs/board/mcGameBoard
				_PARENT.addChild(_mcGameBoard);
				
				_mcMap = new mcMap(); 						//attach library game/board/mcs/board/mcMap
				_mcGameBoard.addChild(_mcMap);
				_mcMap.x = 65;
				_mcMap.y = 143;
				
				_mcLimits = new mcLimitsCountries();		//attach library game/board/mcs/board/mcLimitsCountries
				_mcLimits.x = -107;
				_mcLimits.y = -78;
				_mcMap.addChild(_mcLimits);
				
				//codigo de inicializacion
				//------------------------
				initPlayers();								//inicializar jugadores	(crear players)
				repartirPaises(_objPlayers.intPlayers);		//repartir paises al azar entre los jugadores actualizando CAKdata
				_objCountries = Countries.getInstance();	//inicia Countries
				_objCountries.init(_mcMap);
				_objCards = Cards.getInstance();			//inicia Cards
				
				_mcMap.setChildIndex(_mcLimits, _mcMap.numChildren - 1);
			}
		}


		/**
		 * Destruye las instancias
		 */
		public function destroy():void
		{
			mTrace("#GameEngine# destroy");
			_isInited = false;
			GameEngine._INSTANCE = null;
		}
		
		
		/**
		 * Congela / descongela los eventos de la clase
		 * @param   freeze 
		 */		
		public function freeze(freeze:Boolean):void
		{
			mTrace("#GameEngine freeze " + freeze);
			_isFreeze = freeze;
			
			_objCountries.freeze(_isFreeze);
			_objCards.freeze(_isFreeze);
			_objPlayers.freeze(_isFreeze);
		}		
		
		
//_________________________________________________________________________________ Private Methods


		/**
		 * inicializar jugadores
		 */		
		private function initPlayers():void
		{
			_objPlayers = new Players(); //com.conelmate.cak.players.Players
			_objPlayers.init();			
			
			//hardcodear la creacion de varios jugadores para probar el codigo
			_objPlayers.createPlayer(_objPlayers.NEGRO, 	"Ruben");
			_objPlayers.createPlayer(_objPlayers.ROJO, 		"Maximo");
			_objPlayers.createPlayer(_objPlayers.AMARILLO,	"Roque");
			_objPlayers.createPlayer(_objPlayers.AZUL, 		"Sebas");
			_objPlayers.createPlayer(_objPlayers.BLANCO, 	"Seba");
			_objPlayers.createPlayer(_objPlayers.VERDE, 	"Seba2");
		}
		

		/**
		 * inicializar rondas
		 */		
		private function initRounds():void
		{
			_objRounds = new Rounds(); //com.conelmate.cak.game.rounds.Rounds
			_objRounds.init();
			
			//verificar el funcionamiento
			trace("Crear ronda: "+_objRounds.createRound("Initialize"));
		}


		/**
		 * reparte entre los jugadores los 72 paises al azar
		 */		
		private function repartirPaises(intPlayers:uint):void
		{
			var objCAKdata = CAKdata.getInstance();
			var intCountries:uint = objCAKdata.intCountries;
			var arrSuffle = createArraySuffle(intCountries);			
			var countriesPerPlayer:uint = Math.abs(intCountries / intPlayers);
			
			var i:uint;
			var arr:Array;
			var playerColor:String;
			
			//repartir los 72 paises entre los jugadores
			for(i = 0; i < intPlayers; i++){
				arr = new Array();
				for(var n:uint = 0; n < countriesPerPlayer; n++) if(arrSuffle.length > 0) arr.push(arrSuffle.shift());
				playerColor = _objPlayers.getPlayer(i).pColor;
				objCAKdata.setPlayer(playerColor, arr, _objPlayers.getPlayer(i));
			}
			
			//si son 5 jugadores, sobran 2 paises, que se reparten entre los 2 primeros jugadores
			for(i = 0; i < intPlayers; i++){
				if(arrSuffle.length > 0){
					arr = new Array();
					arr.push(arrSuffle.shift());
					playerColor = _objPlayers.getPlayer(i).pColor;
					objCAKdata.setPlayer(playerColor, arr);
				}
			}			
		}


		/**
		 * auxiliar para crear un array desordenado de p numeros
		 * @param   p :cantidad de numeros a generar
		 */		
		private function createArraySuffle(p:uint):Array
		{
			var arrNumbers:Array = new Array();
			for(var i:uint = 1; i < p+1; i++) arrNumbers.push(i);
			
			var ret:Array = new Array();
			while(arrNumbers.length > 0){
				var rnd:uint = Math.floor(Math.random() * arrNumbers.length);
				ret.push(arrNumbers[rnd]);
				arrNumbers.splice(rnd, 1);
			}
			return ret;
		}


//_________________________________________________________________________________ GETTERS
//_________________________________________________________________________________ SETTERS		
		
	}
}

class SingletonEnforcer{}